import type { ParamConfig } from '@/types/api/other'
import type { DictCodeRequest } from '@/types/api/public'
import type { RecordListItem } from '@/types/api/record'
import type { LoginRes } from '@/types/api/user'
import type { ProductConfiguration } from '@/types/cache'
import type { Relationship } from '@/types/user'
import type { Ref } from 'vue'
import { dictApi, otherApi } from '@/request/api'
import { useConsole, useCurrentPage, useModal, useRelaunch } from '@/utils'
import { to } from 'await-to-js'
import { isNil } from 'lodash-es'
import { defineStore } from 'pinia'

import { computed, ref, watch } from 'vue'
import { any as zany, array as zarray, object as zobject, record as zrecord, string as zstring } from 'zod'

interface MenuButtonStyle extends UniNamespace.GetMenuButtonBoundingClientRectRes {
  /** 支付宝小程序自定义按钮 */
  optionMenuWidth?: number
  /** 支付宝小程序自定义按钮 */
  optionMenuHeight?: number
  /** 支付宝小程序自定义按钮 */
  optionMenuTop?: number
  /** 支付宝小程序自定义按钮 */
  optionMenuButtom?: number
  /** 支付宝小程序自定义按钮 */
  optionMenuLeft?: number
  /** 支付宝小程序自定义按钮 */
  optionMenuRight?: number
}

interface LeftButtonItemStyle {
  width: number
  height: number
  top: number
  right: number
  bottom: number
  left: number
}
/** 支付宝小程序左边按钮 */
interface LeftButtonStyle {
  /** 按钮图标的布局位置信息 */
  backButtonIcon: LeftButtonItemStyle
  /** 按钮点击响应区域的布局位置信息 */
  backButtonInteractive: LeftButtonItemStyle
  /** 首页按钮图标的布局位置信息 */
  homeButtonIcon: LeftButtonItemStyle
}

/** 设备信息 */
export const useDevice = defineStore('device', () => {
  // const deviceInfo = uni.getDeviceInfo()
  const windowInfo = {} as UniNamespace.GetWindowInfoResult
  // #ifdef H5 || MP-WEIXIN || MP-ALIPAY
  Object.assign(windowInfo, uni.getWindowInfo())
  useConsole?.log('windowInfo', windowInfo)
  // #endif

  const menuButtonStyle = {} as MenuButtonStyle
  // #ifdef MP-ALIPAY || MP-WEIXIN || MP-TOUTIAO || MP-KUAISHOU
  Object.assign(menuButtonStyle, uni.getMenuButtonBoundingClientRect())
  // #endif
  // #ifdef MP-KUAISHOU
  Object.assign(menuButtonStyle, ks.getMenuButtonBoundingClientRect())
  // #endif
  const leftButtonStyle = {} as LeftButtonStyle
  // #ifdef MP-ALIPAY
  Object.assign(leftButtonStyle, my.getLeftButtonsBoundingClientRect)
  // #endif

  // const deviceName = `${deviceInfo.deviceBrand} ${deviceInfo.deviceModel} ${deviceInfo.system}`

  return {
    // deviceInfo,
    // deviceName,
    windowInfo,
    menuButtonStyle,
    leftButtonStyle,
  }
})

/** 用户信息 */
export const useProfile = defineStore('profile', () => {
  /** 已经登录 */
  const isLoggedIn = ref(false)
  /** 用户信息 */
  const userInfo = ref<Partial<LoginRes['user']>>()
  /** 权限信息 */
  const permission=ref()

  /** 已经实名 */
  const hasRealNameVerified = computed(() => {
    if (!isLoggedIn.value) {
      return false
    }
    const zparse = zarray(zstring().startsWith('http')).min(2).safeParse(userInfo.value?.idCardUrl)
    return zparse.success
  })
  /** 用户关系 */
  const userRelationship = ref<Relationship>()

  /** 检测本地是否有登录后的缓存数据结构（token、用户信息） */
  function checkCache() {
    const token = uni.getStorageSync('token')
    const userInfo = uni.getStorageSync('userInfo')
    const zparse = zobject({
      token: zstring().min(1),
      userInfo: zrecord(zany()),
    }).safeParse({
      token,
      userInfo: userInfo ? JSON.parse(userInfo) : userInfo,
    })
    return zparse.success
  }

  /** 登录状态守卫 */
  async function loginGuard() {
    if (isLoggedIn.value) {
      return
    }
    const { confirm } = await useModal({
      title: '温馨提示',
      content: '您还未登录，请先登录',
      cancelText: '取消',
      confirmText: '去登录',
    })
    if (confirm) {
      useRelaunch('/me/login', {
        from: btoa(useCurrentPage().fullPath),
      })
    }
    return Promise.reject(new Error('Login guard'))
  }

  /** 初始化（登录状态、用户信息） */
  function init() {
    userInfo.value = JSON.parse(uni.getStorageSync('userInfo'))
    userInfo.value = JSON.parse(uni.getStorageSync('permission'))
    userRelationship.value = uni.getStorageSync('userRelationship') || { shopId: 0 }
    isLoggedIn.value = true
  }

  /** 设置用户关系 */
  function setUserRelationship(data: Relationship) {
    userRelationship.value = {
      flowState: Number.parseInt(`${data.flowState}`),
      shopId: Number.parseInt(`${data.shopId}`),
      promotionAccount: data.promotionAccount,
    }
    uni.setStorageSync('userRelationship', userRelationship.value)
  }

  /** 更新用户信息 */
  function updateItems(data: Partial<Record<keyof LoginRes['user'], any>>) {
    userInfo.value = {
      ...userInfo.value,
      ...data,
    }
    uni.setStorageSync('userInfo', userInfo.value)
  }

  /** 清除登录信息（登录状态、用户信息） */
  function clear() {
    isLoggedIn.value = false
    userInfo.value = undefined
    userRelationship.value = undefined
    uni.removeStorageSync('token')
    uni.removeStorageSync('userInfo')
    uni.removeStorageSync('userRelationship')
  }

  return {
    /** 已经登录 */
    isLoggedIn,
    /** 用户信息 */
    userInfo: computed(() => userInfo.value as LoginRes['user']),
    /** 权限信息 */
    permission: computed(() => permission.value),
    /** 已经实名 */
    hasRealNameVerified,
    /** 用户关系 */
    userRelationship,

    /** 检查本地是否有登录后的缓存数据结构（token、用户信息） */
    checkCache,
    /** 登录状态守卫 */
    loginGuard,
    /** 初始化（登录状态、用户信息） */
    init,
    /** 设置用户关系 */
    setUserRelationship,
    /** 更新用户信息 */
    updateItems,
    /** 清除登录信息（登录状态、用户信息） */
    clear,
  }
})

/** 应用配置 */
export const useAppConfig = defineStore('appConfig', () => {
  const appletSet = ref() as Ref<ParamConfig['appletSet']>
  const productDetails = ref() as Ref<ParamConfig['productDetails']>
  const rentExplain = ref() as Ref<ParamConfig['rentExplain']>
  const appletTagSet = ref() as Ref<ParamConfig['appletTagSet']>
  const wxPayConfig = ref() as Ref<ParamConfig['wxPayConfig']>

  const hidePayBtn = computed(() => {
    return appletSet.value?.hidePayBtn?.value === '1'
  })

  async function fetchData() {
    const [err, res] = await to(otherApi.getParamConfig({ t: new Date().valueOf() }))
    if (err) {
      return
    }

    const data: Record<string, any> = res.reduce((a, b) => ({ ...a, ...b }))
    useConsole?.log('useAppConfig:fetchData:reduce', data)

    appletSet.value = data.appletSet
    productDetails.value = data.productDetails
    rentExplain.value = data.rentExplain
    appletTagSet.value = data.appletTagSet
    wxPayConfig.value = data.wxPayConfig
  }

  return {
    appletSet,
    productDetails,
    rentExplain,
    appletTagSet,
    wxPayConfig,

    /** 隐藏支付按钮 */
    hidePayBtn,

    fetchData,
  }
})

/** 应用状态 */
export const useAppStatus = defineStore('appStatus', () => {
  /** 用于标识小程序 onLaunch 完成（用户关系已经保存） */
  const launchComplate = ref(false)

  return {
    /** 用于标识小程序 onLaunch 完成（用户关系已经保存） */
    launchComplate,
  }
})

/** 全局临时数据 */
export const useGlobalCache = defineStore('mdmCache', () => {
  const currentProductConfiguration = ref<ProductConfiguration>()
  const currentOrderId = ref<number>()

  watch(currentOrderId, (val) => {
    if (!isNil(val)) {
      useConsole?.log('currentOrderId', val)
    }
  })

  return {
    /** 当前选择的产品的下单配置 */
    currentProductConfiguration,
    /** 订单页跳去签署合同、代扣时记一下当前订单 id 用于回程刷新 */
    currentOrderId,
  }
})
/** 字典 */
export const useDict = defineStore('dict', () => {
  const dictList = ref() as Ref<Record<string, any>>

  async function init(params: DictCodeRequest) {
    const [err, res] = await to(dictApi.dictList(params))
    if (err) {
      return
    }
    dictList.value = res
  }
  function operateDict(x: string) {
    if (!dictList.value)
      return
    return dictList.value.find((item: any) => item.itemValue === x)
  }

  return {
    dictList,
    init,
    operateDict,
  }
})
/** 审批详情 */
export const useRecord = defineStore('record', () => {
  const recordDetails = ref() as Ref<RecordListItem>
  async function init() {
    recordDetails.value = JSON.parse(uni.getStorageSync('useRecord'))
  }
  async function update(item: RecordListItem) {
    uni.setStorageSync('useRecord', JSON.stringify(item))
  }

  return {
    update,
    init,
    recordDetails,
  }
})
